
;--- implements GetEnvironmentVariableA()

	.386
if ?FLAT
	.MODEL FLAT, stdcall
else
	.MODEL SMALL, stdcall
endif
	option casemap:none
	option proc:private

	include winbase.inc
	include dkrnl32.inc
	include macros.inc


@swapdses macro
ife ?FLAT
	mov eax, es
	push ds
	mov ds, eax
	pop es
endif
	endm

PUSHADS struct
rEdi	dd ?
rEsi	dd ?
rEbp	dd ?
		dd ?
rEbx	dd ?
rEdx	dd ?
rEcx	dd ?
rEax	dd ?
PUSHADS ends

	.CODE

;--- maxsize may be NULL!

GetEnvironmentVariableA proc public uses esi edi ebx key:ptr BYTE, buffer:ptr BYTE, maxsize:dword

local	keysize:dword
local	pEnv:dword

	invoke lstrlen, key
	mov keysize, eax

	mov ah, 62h
	int 21h
	push ds
	mov ds, ebx
	mov bx, ds:[2ch]
	pop ds
	mov ax, 6
	int 31h

ife ?FLAT
	push es
	push gs
	pop es
@flat equ <es>
else
@flat equ <ds>
endif
	jc error		;C if environment is NULL

	push cx
	push dx
	pop edi

	.while (byte ptr @flat:[edi])
		mov esi,key
		mov ecx,keysize
		mov edx, edi
		repz cmpsb
		.if (ZERO? && byte ptr @flat:[edi] == '=')
			inc edi
			mov esi,edi
			or ecx,-1
			mov al,0
			repnz scasb
			sub edi, esi
			mov eax, edi       ; size of value+00 in eax
			cmp eax, maxsize
			ja done
			push eax
			mov edi,buffer
			mov ecx,eax
			@swapdses
			rep movsb
			@swapdses
			pop eax
			dec eax
			jmp done
		.endif
		mov edi, edx
		mov al, 0
		or ecx, -1
		repnz scasb
	.endw
error:
	xor eax, eax
done:
	mov edx, esi	; v3.8: return address of value in source in edx ( for GetCommandLineA )
ife ?FLAT
	pop es
endif
ifdef _DEBUG
	.if (eax && buffer && (eax < maxsize))
		@strace <"GetEnvironmentVariableA(", &key, ", ", buffer, ", ", maxsize, ")=", eax, " [", &buffer, "]">
	.else
		@strace <"GetEnvironmentVariableA(", &key, ", ", buffer, ", ", maxsize, ")=", eax>
	.endif
endif
	ret
	align 4

GetEnvironmentVariableA endp

;--- this is an internal function

_GetEnvironmentVariableInt proc public uses esi ebx pszName:ptr BYTE

	sub esp, 128
	@loadesp esi
	invoke GetEnvironmentVariable, pszName, esi, 128
	.if (eax)
		mov ecx, eax
		xor edx, edx
		mov bl,0
		.if ((ecx >= 2) && (word ptr [esi] == "x0"))
			lodsw
			dec ecx
			dec ecx
			inc bl
		.endif
		.while (ecx)
			lodsb
			sub al,'0'
			movzx eax,al
			.if (bl)
				shl edx,4
			.else
				add edx, edx
				lea edx,[edx+edx*4]
			.endif
			add edx, eax
			dec ecx
		.endw
		mov eax, edx
	.endif
	add esp,128
	ret
	align 4

_GetEnvironmentVariableInt endp

	end
